package FC.AG;

public class ElementoGA implements Comparable {

    protected String valor;
    protected double avaliacao;

    public boolean equals(ElementoGA outro) {
        //Usada para testar se dois indivíduos são iguais - importante
        //quando formos ver os módulos de população mais avançados
        return (valor.equals(outro.getValor()));
    }

    public int compareTo(Object outro) {
        //Será usada na hora de inserir os elementos em ordem em uma população
        //para o GA com steady state (capítulo 7)
        int retorno = -1;
        ElementoGA aux = (ElementoGA) outro;
        if (avaliacao > aux.getAvaliacao()) {
            retorno = 1;
        }
        if (avaliacao == aux.getAvaliacao()) {
            retorno = 0;
        }
        return (retorno);
    }

    public double calculaAvaliacao(String valorUsuario) {
        double nota = 0;
        //System.out.println("valor: " + valor + "  t: " + this.valor.length());
        for (int i = 0; i < this.valor.length(); i++) {
            if (this.valor.charAt(i) != ',') {
                int x = Integer.parseInt(this.valor.charAt(i) + "");
                int y = Integer.parseInt(valorUsuario.charAt(i) + "");
                nota += Math.abs(x - y + 0.0f);
            }
        }
        System.out.println("Nota: " + nota);

        this.avaliacao = (1 - (nota / 100));
        /*if (nota == 0) {
         this.avaliacao = 1;
         } else if (nota >= 11) {
         this.avaliacao = (1 - (nota / 100));
         } else if (nota >= 7) {
         this.avaliacao = 0.75 - (nota / 100);
         } else if (nota >= 5) {
         this.avaliacao = 0.5 - (nota / 100);
         } else {
         this.avaliacao = 0.25 - (nota / 100);
         }*/
        return (this.avaliacao);
    }

    public double getAvaliacao() {
        return (this.avaliacao);
    }

    public String getValor() {
        return (this.valor);
    }

    public void setValor(String aux) {
        this.valor = aux;
    }

    protected void inicializaElemento(int tamanho) {
        int i;
        this.valor = "";
        for (i = 0; i < tamanho; ++i) {
            double random = Math.random();
            if (random < 0.25) {
                this.valor = this.valor + "0";
            } else if (random < 0.5) {
                this.valor = this.valor + "1";
            } else if (random < 0.75) {
                this.valor = this.valor + "2";
            } else {
                this.valor = this.valor + "3";
            }
        }
        System.out.println("Elemento: " + valor);
    }

    /**
     * *************
     */
    /* Construtores */
    /**
     * *************
     */
    public ElementoGA(String novoValor) {
        this.valor = novoValor;
    }

    public ElementoGA(int tamanho) {
        inicializaElemento(tamanho);
    }
    
    public ElementoGA() {
        this(11);
    }

    /**
     * *********************
     */
    /* Operadores Geneticos */
    /**
     * *********************
     */
    public void mutacao(double chance) {
        int i;
        int tamanho = this.valor.length();
        String aux, inicio, fim;
        for (i = 0; i < tamanho; i++) {
            if (java.lang.Math.random() < chance) {
                aux = this.valor.substring(i, i + 1);
                if (aux.equals("0")) {
                    aux = "1";
                } else if (aux.equals("1")) {
                    aux = "2";
                } else if (aux.equals("2")) {
                    aux = "3";
                } else {
                    aux = "0";
                }
                inicio = this.valor.substring(0, i);
                fim = this.valor.substring(i + 1, tamanho);
                this.valor = inicio + aux + fim;
            }
        }
    }

    public void mutacao() {
        this.mutacao(0.005);
    }

    public ElementoGA crossoverUmPonto(ElementoGA outroPai) {
        String aux1;
        ElementoGA retorno = null;
        int pontoCorte = (new Double(java.lang.Math.random() * this.valor.length())).intValue();
        //System.out.println("Ponto de Corte: "+pontoCorte);
        //System.out.println("Valor1: "+this.valor);
        //System.out.println("Valor2: "+outroPai.valor);
        if (java.lang.Math.random() < 0.5) {
            aux1 = this.valor.substring(0, pontoCorte) + outroPai.getValor().
                    substring(pontoCorte, outroPai.getValor().length());
        } else {
            aux1 = outroPai.getValor().substring(0, pontoCorte) + this.valor.
                    substring(pontoCorte, this.valor.length());
        }
        try {
            retorno = (ElementoGA) outroPai.getClass().newInstance();
            retorno.setValor(aux1);
        } catch (Exception e) {
        }
        //System.out.println("valor filho: "+retorno.valor);
        return (retorno);
    }

    /**
     * *****************************
     */
    /* Metodos Basicos de Classe    */
    /**
     * *****************************
     */
    public String toString() {
        return ("String:" + this.valor + "\nAvaliacao:" + this.avaliacao);
    }
}